import GameData_blxf from "../GameData/GameData";
import { ConfigModule_blxf } from "../Module/ConfigModule";
import { NumModule_blxf } from "../Module/NumModule";
import { UtilsModule_blxf } from "../Module/UtilsModule";
import { BundleManager_blxf } from "./BundleManager";
import { EnumManager_blxf } from "./EnumManager";

/** 游戏分包归类 */
enum STATETYPE {
    NewFieldStart      = 1,
    NonQuotesField     = 2,
    QuotesField        = 3,
    FieldSeparator     = 4,
    QuoteInQuotesField = 5,
    RowSeparator       = 6,
    Error              = 7,
}

let Row = function () {
    this.m_header = [];
    this.m_values = [];
    this.push_back = function (value) {
        this.m_values.push(value);
    };

    this.setHeader = function (header) {
        this.m_header = header;
    };

    this.getSize = function () {
        return this.m_values.length;
    };

    this.getValueByKey = function (key) {
        for (var i = 0; i < this.m_header.length; ++i) {
            if (this.m_header[i] === key) {
                return this.m_values[i];
            }
        }
        cc.log("error: no key by m_values!");
        return null;
    };
};


const {ccclass, property} = cc._decorator;

/** CSV管理器 */
@ccclass
export class CsvManager_blxf {

    private constructor() { }

    private static _CsvManager_blxf: CsvManager_blxf = new CsvManager_blxf();

    public static get instance (){
        return this._CsvManager_blxf;
    }


    /** 游戏CSV列表 */
    _gameCsvData: object[] = [];

    /** 游戏CSV配置表名 */
    _csvCfgName: string = 'CsvConfig';
    
    /** 预制体配置数据 */
    _PrefabConfigData: object[] = [];

    /** 已加载CSV数 */
    _loadCsvNum: number = 0;

    /** 商品数据 */
    _shopData: any = {};

    /** 加载游戏CSV */
    loadGameCsv_blxf ( cb: any ) {
        this.loadCsvConfig_blxf(()=>{
            this._loadCsvNum = 0;
            this.loadOtherConfig_blxf( cb );
        })
    }

    /** 加载CSV配置列表 */
    loadCsvConfig_blxf ( cb: any ) {
        this.loadCsv_blxf( this._csvCfgName, ( data: object[] )=>{
            this._gameCsvData = JSON.parse(JSON.stringify(data));

            cb && cb();
        });
    }

    /** 加载其它配置表 */
    loadOtherConfig_blxf ( cb: any ) {
        cb && cb( this._loadCsvNum / this._gameCsvData.length );

        let _csvCfgData: object = this._gameCsvData[ this._loadCsvNum ];
        if ( !_csvCfgData ) return;
        // let { CsvName, Msg, CsvPath } = item;
        let _csvName: string = _csvCfgData['CsvName'];
        let _csvPath: string = _csvCfgData['CsvPath'];
        _csvPath = `${_csvPath ? `${_csvPath}/` : ''}${_csvName}`;
        _csvName && this.loadCsv_blxf( _csvPath, ( data: object[] ) =>{
            this[`_${_csvName}Data`] = JSON.parse(JSON.stringify(data));
            // UtilsModule_blxf.instance.Log_blxf(`loadCsv_blxf >> ${_csvName}, ${_csvPath}, ${this[`_${_csvName}Data`]}`);
            // cc.log('loadCsv_blxf >> _csvName', _csvPath, this[`_${_csvName}Data`]);

            this._loadCsvNum += 1;
            this.loadOtherConfig_blxf( cb );
        })
    }

    /**
     * 通过文件名获取Csv解析后数据
     * @param fileName csv文件名
     */
    getCsvDataByName_blxf ( fileName: string ) {
        let _csvData: object[] = this[`_${fileName}Data`];
        if ( _csvData ) return UtilsModule_blxf.instance.getCopyData_blxf( _csvData );

        UtilsModule_blxf.instance.Log_blxf(`获取Csv数据失败 >> fileName = ${fileName}`, 2);
    };

    /**
     * 获取文字配置
     * @param texId 文字id 
     */
    getCfgText_blxf ( textId: string ) {
        let { CSV_TEXT } = EnumManager_blxf.instance.getGameCsvType();
        let _cfgTextList: any[] = this.getCsvDataByName_blxf( CSV_TEXT );
        if ( !_cfgTextList ) return UtilsModule_blxf.instance.Log_blxf(`获取文字配置失败 >> ${textId}`);
        
        let _textData: any = _cfgTextList.find( item => item.TextId == textId );
        if ( !_textData ) return textId;

        let _textType = UtilsModule_blxf.instance.getTextType_blxf();
        let _propName: string = `Text_${_textType}`;
        return _textData[ _propName ];
    }

    /**
     * 获取预制体数据
     * @param pfName 预制体名字
     */
    getPrefabData_blxf ( pfName: string ) {
        let _pfData = this._PrefabConfigData.find( item =>{
            return item['PrefabId'] == pfName;
        })
        if ( _pfData ) return _pfData;
    }

    /**
     * 获取预制体路径
     * @param pfName 预制体名字
     */
    getPrefabPath_blxf ( pfName: string ) {
        let _pfData = this._PrefabConfigData.find( item =>{
            return item['PrefabId'] == pfName;
        })
        if ( _pfData ) return _pfData['PrefabPath'];
        cc.warn('查找预制体配置数据失败 >>', pfName);
    }

    /**
     * 获取动画配置数据
     * @param spineId 动画id
     */
    getSpineDataById_blxf ( spineId: string ) {
        let _spineData: any;
        let { CSV_SPINE } = EnumManager_blxf.instance.getGameCsvType();
        let _cfgSpineList: any[] = this.getCsvDataByName_blxf( CSV_SPINE );
        if ( !_cfgSpineList ) return _spineData;

        _spineData = _cfgSpineList.find( spineItem =>{
            return spineItem.SpineId == spineId;
        })

        return _spineData;
    }

    /** 获取商品数据 */
    getShopData_blxf ( shopId: number ) {
        let _shopData: any = this._shopData[ `${shopId}` ];
        if ( _shopData ) return UtilsModule_blxf.instance.getCopyData_blxf( _shopData );

        let { CSV_SHOP } = EnumManager_blxf.instance.getGameCsvType();
        let _shopCfgList: any[] = CsvManager_blxf.instance.getCsvDataByName_blxf( CSV_SHOP );
        _shopData = _shopCfgList.find( item => {
            return Number(item.ShopId) == Number(shopId);
        } );

        this._shopData[ `${shopId}` ] = _shopData;

        return _shopData;
    }


    /** 获取摊位补货数据 */
    getVendorAddShopData_blxf () {
        let { CSV_VENDOR_ADDSHOP } = EnumManager_blxf.instance.getGameCsvType();
        let _cfgVendorAddShopData = CsvManager_blxf.instance.getCsvDataByName_blxf( CSV_VENDOR_ADDSHOP );
        // 初始补货数
        let _vendorNum: number = GameData_blxf.instance.getVendorNum_blxf();
        let _addShopData = _cfgVendorAddShopData.find( addShopItem =>{
            return addShopItem.VendorNum == _vendorNum;
        })

        return _addShopData;
    }

    /**
     * 获取菜篮子集满奖励
     * @param shopNum 集满数 
     * @returns 返回奖励数据
     */
    getTargetRewardByNum_blxf ( shopNum: number ){
        let _rewardData: any;
        let { CSV_TARGET_REWARD } = EnumManager_blxf.instance.getGameCsvType();
        let _cfgRewardList: any[] = this.getCsvDataByName_blxf( CSV_TARGET_REWARD );
        if ( !_cfgRewardList ) return _rewardData;

        _rewardData = _cfgRewardList.find( rewardItem =>{
            return rewardItem.TargetShopNum == shopNum;
        })

        return _rewardData;
    }

    /**
     * 获取音频数据
     * @param audioId 音频id 
     * @returns 返回音频数据
     */
    getAudioData_blxf ( audioId: number ) {
        let _audioData: any;
        let { CSV_AUDIO } = EnumManager_blxf.instance.getGameCsvType();
        let _cfgAudioList: any[] = this.getCsvDataByName_blxf( CSV_AUDIO );
        if ( !_cfgAudioList ) return _audioData;

        _audioData = _cfgAudioList.find( audioItem =>{
            return audioItem.AudioId == audioId;
        })

        if ( !_audioData ) return _audioData;

        let { AudioDirName, AudioName } = _audioData;
        _audioData._audioPath = `${AudioDirName}/${AudioName}`;

        return _audioData;
    }

    /**
     * 获取摊位卸货数据
     * @param vendorNum 摊位数 
     * @returns 卸货数据
     */
    getVendorRemoveShopData_blxf ( vendorNum: number ) {
        let _removeData: any;

        let { CSV_VENDOR_REMOVESHOP } = EnumManager_blxf.instance.getGameCsvType();
        let _cfgRemoveData: any[] = this.getCsvDataByName_blxf( CSV_VENDOR_REMOVESHOP );
        if ( !_cfgRemoveData ) return _removeData;

        _removeData = _cfgRemoveData.find( audioItem =>{
            return audioItem.VendorNum == vendorNum;
        })

        return _removeData;
    }

    /** 获取龙等级数据 */
    getDragonData_blxf ( dragonLv: number ) {
        let _dragonData: any;

        let { CSV_DRAGON } = EnumManager_blxf.instance.getGameCsvType();
        let _cfgDragonData: any[] = this.getCsvDataByName_blxf( CSV_DRAGON );
        if ( !_cfgDragonData ) return; _dragonData;

        _dragonData = _cfgDragonData.find( dragonItem =>{
            return dragonItem.Level == dragonLv;
        })

        return _dragonData;
    }

    /** 获取装饰数据 */
    getBuildData_blxf ( buildId: number = null ) {
        let _buildData: any = {};

        // let { CSV_AUTO_BUILD } = EnumManager_blxf.instance.getGameCsvType();
        // _buildData = this.getCsvDataByName_blxf( CSV_AUTO_BUILD );

        // if ( buildId ) {
        //     _buildData = _buildData.find( item => item['BuildId'] == buildId );
        // }

        return _buildData;
    }

    /**
     * 获取等级数据
     * @param type 类型
     * @param level 等级
     */
    getBuildLevelData_blxf ( type: number, level: number, unlockData: any ) {
        let _levelData: any;

        let { CSV_AUTO_VENDOR_LEVEL, CSV_AUTO_TARGET_LEVEL } = EnumManager_blxf.instance.getGameCsvType();
        let _csvName: string = type == 1 ? CSV_AUTO_VENDOR_LEVEL : CSV_AUTO_TARGET_LEVEL;
        let _levelDataList: any[] = this.getCsvDataByName_blxf( _csvName );

        let _checkTotalNum: number = unlockData['checkNum'], _consumeTotalNum: number = unlockData['consumeNum'];
        _levelDataList.forEach( item =>{
            let _item: any = UtilsModule_blxf.instance.getCopyData_blxf( item );

            let _level: number = Number( _item['Level'] );
            if ( _level > level ) return;

            NumModule_blxf.instance.onParseCfgData_blxf( _item, _level );
            _item['checkNum'] += _checkTotalNum;
            _item['consumeNum'] += _consumeTotalNum;

            let { checkType, checkNum, consumeType, consumeNum } = _item;
            item['Condition'] = `${checkType}_${checkNum}`;
            item['ConsumeStr'] = `${consumeType}_${consumeNum}`;

            _checkTotalNum = _item['checkNum'];
            _consumeTotalNum = _item['consumeNum'];
        })
        
        _levelData = _levelDataList.find( item => item['Level'] == level );
        // if ( !_levelData ) {
        //     _levelData = _levelDataList.find( item => item['Level'] == '?' );
        //     _levelData[ 'Level' ] = level;
        // }

        _levelData && NumModule_blxf.instance.onParseCfgData_blxf( _levelData, level );

        return _levelData;
    }

    /**
     * 获取菜摊和菜篮数据
     * @param type 类型（1菜摊、2菜篮）
     * @param id 具体id
     * @returns 返回数据列表
     */
    getVendorAndTargetData_blxf ( type: number = -1, id: number = -1 ) {
        let _dataList: any[];

        let { CSV_AUTO_VENDOR_AND_TARGET } = EnumManager_blxf.instance.getGameCsvType();
        _dataList = this.getCsvDataByName_blxf( CSV_AUTO_VENDOR_AND_TARGET );

        if ( type != -1 ) {
            _dataList = _dataList.filter( item =>{
                let { ID, Type } = item;
                let _isId: boolean = id == -1 || ID == id;
                return Type == type && _isId;
            })
        }

        _dataList.forEach( item =>{
            let { ID, Type, AtlasName, ImgName } = item;
            Object.assign(item, { path: AtlasName, imgName: ImgName });

            NumModule_blxf.instance.onParseCfgData_blxf( item );

            let { checkType, checkNum } = item;

            item['_isVendor'] = Type == 1;

            item['data'] = item['_isVendor'] ? GameData_blxf.instance.getAutoVendorData_blxf( ID ) : GameData_blxf.instance.getAutoTargetData_blxf( ID );
            item['_isUnlock'] = !!item['data'];
            item['level'] = 1;
            if ( item['_isUnlock'] ) {
                let { vendorLv, targetLv } = item['data'];
                item['level'] = item['_isVendor'] ? vendorLv : targetLv;
            }

            // 下级数据
            let _nowLv: number = item['_isUnlock'] ? item['level'] : 1;
            let _nextLv: number = item['_isUnlock'] ? _nowLv + 1 : _nowLv;
            item['nowLevelData'] = this.getBuildLevelData_blxf( Type, _nowLv, item );
            item['levelData']    = this.getBuildLevelData_blxf( Type, _nextLv, item );

            // 满级
            if ( !item['levelData'] ) return;

            if ( item['_isUnlock'] ) {
                let { consumeType, consumeNum } = item['levelData'];
                item['consumeNum'] = consumeNum;
                item['consumeType'] = consumeType;

                checkType = item['levelData'].checkType;
                checkNum  = item['levelData'].checkNum;

                item['checkType'] = checkType;
                item['checkNum'] = checkNum;
            }

            // 是否满足条件
            let _isCondition: boolean = NumModule_blxf.instance.onCheckNum_blxf( checkType, checkNum );
            item['isCondition'] = _isCondition;

            let _isConsume: boolean = NumModule_blxf.instance.onCheckNum_blxf( item.consumeType, item.consumeNum );
            item['isConsume'] = _isConsume;
        })
        
        return _dataList;
    }

    /** 获取装饰数据 */
    getDecorationData_blxf ( type: number = 1, decorationId: number = null ) {
        let _dataList: any[], _csvName: string;

        let { checkH, checkW } = ConfigModule_blxf.instance;
        let { CSV_AUTO_BUILD, CSV_ROOM_BUILD, CSV_KITCHEN_BUILD } = EnumManager_blxf.instance.getGameCsvType();
        switch ( type ) {
            case 1 : _csvName = CSV_AUTO_BUILD; break;
            case 2 : _csvName = CSV_ROOM_BUILD; break;
            case 3 : _csvName = CSV_KITCHEN_BUILD; break;
        }
        _dataList = this.getCsvDataByName_blxf( _csvName );

        if ( decorationId ) {
            _dataList = _dataList.filter( item => item.BuildId == decorationId );
        } else {
            _dataList = _dataList.filter( item => item.ConsumeStr );
        }

        _dataList.forEach( item =>{
            let { BuildId, Name, AtlasName, ImgName, PosX, PosY, ZIndex, UpdateY, UpdateX, ScaleX, ScaleY, Height, BindIdStr } = item;

            let _posX: number = Number( PosX );
            let _posY: number = Number( PosY );
            if ( UpdateY == 1 ) _posY += (_posY > 0 ? 1 : -1) * checkH;
            if ( UpdateX == 1 ) _posX += (_posX > 0 ? 1 : -1) * checkW;

            item['id']       = BuildId;
            item['name']     = Name;
            item['imgName']  = ImgName;
            item['path']     = AtlasName;
            item['position'] = cc.v3( _posX, _posY, 0 );
            item['zIndex']   = Number( ZIndex || 0 );
            item['scaleX']   = ScaleX ? Number(ScaleX) : 1;
            item['scaleY']   = ScaleY ? Number(ScaleY) : 1;
            item['height']   = Height ? Number(Height) : 0;
            item['bindIds']  = BindIdStr ? BindIdStr.split('&') : [];
            item['isUnlock'] = !!GameData_blxf.instance.getDecorationDataByType_blxf( type, item['id'] );

            NumModule_blxf.instance.onParseCfgData_blxf( item );

            // 有限制
            // let { consumeType, consumeNum } = item;
            // item['isConsume'] = NumModule_blxf.instance.onCheckNum_blxf( consumeType, consumeNum );
        })

        return decorationId ? _dataList[0] : _dataList;
    }


    /**
     * 获取关卡数据
     * @param passId 关卡id
     * @returns 返回关卡数据
     */
    getPassData_blxf ( passId: number = null, maxNum: number = 99 ) {
        let _passData: any[] = [];
        if ( !passId ) passId = GameData_blxf.instance.getJengaPassNum_blxf();
        
        let { CSV_PASS } = EnumManager_blxf.instance.getGameCsvType();
        let _passCfgList: any[] = CsvManager_blxf.instance.getCsvDataByName_blxf( CSV_PASS );

        let _cfgBaseN: number = 6;
        let { gridRows, gridColumns } = ConfigModule_blxf;
        let _cfgId: number = Math.floor( (passId - 1) / _cfgBaseN ) + 1;
        let _baseN: number = (passId - 1) % _cfgBaseN + 1;
        _passCfgList.forEach( item =>{
            let { ID } = item;
            if ( ID != _cfgId ) return;
            let _rowStr: string = item[`R${_baseN}`];
            let rowN: number = Number( _rowStr.split('_')[1] );
            for ( let colN = 1; colN <= gridColumns; colN++ ) {
                let index: number =  ( rowN - 1 ) * gridColumns + colN;
                let value: any = item[ `C${_baseN}_${colN}` ];
                let condition: any = value > 9 ? value : '';
                let conditionPercent: string = `${Math.round( condition / maxNum * 100 )}%`;
                let _isGrid: boolean   = /*value != 0 ||*/ value != '';
                let _isVideo: boolean  = value == 9 || value == 'G';
                let _isUnlock: boolean = value == 1 || _isGrid && !_isVideo && !condition; 
                _passData.push({ rowN, colN, index, value, condition, conditionPercent, _isGrid, _isVideo, _isUnlock });
            }
            // UtilsModule_blxf.instance.Log_blxf([ 'item >>', item ]);
        })

        UtilsModule_blxf.instance.Log_blxf( [ `关卡${passId}数据 ==>`, _passData ]);
        return _passData;
    }

    /** 获取关卡派发配置数据 */
    getPassSendData_blxf () {
        let _sendData: any;
        let _passNum: number = GameData_blxf.instance.getJengaPassNum_blxf();;

        let { CSV_SEND } = EnumManager_blxf.instance.getGameCsvType();
        let _sendCfgList: any[] = CsvManager_blxf.instance.getCsvDataByName_blxf( CSV_SEND );
        
        _sendCfgList.forEach( item =>{
            let { PassNum } = item;
            let _isGt: boolean = _passNum - PassNum >= 0;
            if ( _isGt ) _sendData = item;
        })

        UtilsModule_blxf.instance.Log_blxf([ `关卡${ _passNum }派发数据 ==>`, _sendData ]);
        return _sendData;
    }

    /**
     * 获取关卡触发数据
     * @param type 1: 复活、2: 关卡进度 3: 空位相关 4: 单个颜色数量 5: 派发素材相关
     * @returns 返回触发数据
     */
    getPassTriggerData_blxf ( type: number ) {
        let _triggerData: any[];

        let { CSV_TRIGGER_CONFIG } = EnumManager_blxf.instance.getGameCsvType();
        let _triggerCfgList: any[] = CsvManager_blxf.instance.getCsvDataByName_blxf( CSV_TRIGGER_CONFIG );

        _triggerData = _triggerCfgList.filter( item =>{
            return item.Type == type;
        })
        
        _triggerData.forEach( item =>{
            let { ConditionParam1, ConditionParam2, ResultParam } = item;
            let [ _minParam1, _maxParam1 ] = ConditionParam1.split('_');
            let [ _minParam2, _maxParam2 ] = ConditionParam2.split('_');
            let [ _resultType, _resultParam ] = ResultParam.split('_');
            item[ 'minParam1' ] = Number( _minParam1 );
            item[ 'maxParam1' ] = Number( _maxParam1 );
            item[ 'minParam2' ] = Number( _minParam2 );
            item[ 'maxParam2' ] = Number( _maxParam2 );
            item[ 'resultType' ] = Number( _resultType );
            item[ 'resultParam' ] = Number( _resultParam );
        });

        return _triggerData;
    }

    /** 获取关卡奖励数据 */
    getPassRewardData_blxf () {
        let _passRewardData: any;
        let { maxPassMax } = ConfigModule_blxf;
        let _passNum: number = GameData_blxf.instance.getJengaPassNum_blxf();
        let _rewardPassNum: number = _passNum;
        if ( _rewardPassNum > maxPassMax ) _rewardPassNum = maxPassMax;

        let { CSV_PASS_REWARD } = EnumManager_blxf.instance.getGameCsvType();
        let _passRewardCfgList: any[] = CsvManager_blxf.instance.getCsvDataByName_blxf( CSV_PASS_REWARD );

        _passRewardData = _passRewardCfgList.find( item => item.PassNum == _rewardPassNum );
        let { RewardStr, FoodId } = _passRewardData;
        let _foodData: any = this.getFoodData_blxf( FoodId );
        let [ _rewardType, _rewardNum ] = RewardStr.split('_');
        _rewardType = Number( _rewardType ), _rewardNum = Number( _rewardNum );
        Object.assign( _passRewardData, { _rewardType, _rewardNum, PassNum: _passNum }, _foodData );

        return _passRewardData;
    }

    

    /** 获取菜品数据列表 */
    getFoodDataList_blxf ( foodType: any = null ) {
        let _foodCfgList: any[];

        let _defType: string = 'CN';
        let _textType = UtilsModule_blxf.instance.getTextType_blxf();
        let { CSV_FOOD } = EnumManager_blxf.instance.getGameCsvType();
        _foodCfgList = CsvManager_blxf.instance.getCsvDataByName_blxf( CSV_FOOD );
        _foodCfgList.forEach( item =>{
            let { FoodId, FoodImgName } = item;
            item[ `FoodName` ] = item[ `FoodName_${_textType}` ] || item[ `FoodName_${_defType}` ];
            item[ `FoodType` ] = item[ `FoodType_${_textType}` ] || item[ `FoodType_${_defType}` ];
            item[ `FoodMsg`  ] = item[ `FoodMsg_${_textType}`  ] || item[ `FoodMsg_${_defType}`  ] ;
            // item[ `FoodImgName` ] = `cp${FoodImgName.split('_')[1]}`;
            item[ '_isUnlock' ] = UtilsModule_blxf.instance.onCheckIsUnlockFoodId_blxf( Number(FoodId) );
        })

        if ( foodType ) {
            _foodCfgList = _foodCfgList.filter( item => item[ `FoodType` ] == foodType );
        }

        return _foodCfgList;
    }

    /** 获取菜品数据 */
    getFoodData_blxf ( foodId: any ) {
        let _foodData: any;

        let _foodCfgList: any[] = this.getFoodDataList_blxf();
        _foodData = _foodCfgList.find( item => item.FoodId == foodId );

        if ( !_foodData ) return;

        let _itemList: any[] = [];
        for ( let n = 1; n <= 10; n++ ) {
            let _value: string = _foodData[ `Color${n}Num` ];
            if ( !_value ) continue;

            let [ _shopId, _num ] = _value.split('_');
            let _shopData: any = this.getShopData_blxf( Number(_shopId) );
            let { ShopName, AtlasName, ImgName } = _shopData || { };
            _itemList.push({ id: n, shopId: _shopId, num: Number(_num), name: ShopName, path: AtlasName, imgName: ImgName });
        }
        _foodData[ 'itemList' ] = _itemList;

        return _foodData;
    }

    /** 获取道具数据列表 */
    getPropDataList_blxf () {
        let _defType: string = 'CN';
        let _textType = UtilsModule_blxf.instance.getTextType_blxf();
        let { CSV_PROP } = EnumManager_blxf.instance.getGameCsvType();
        let _propCfgList: any[] = CsvManager_blxf.instance.getCsvDataByName_blxf( CSV_PROP );
        _propCfgList.forEach( item =>{
            let { ColorStr } = item;
            let [ _r, _g, _b ] = ColorStr.split('_');
            item[ 'propName' ] = item[ `Name_${_textType}` ] || item[ `Name_${_defType}` ];
            item[ 'propMsg' ]  = item[ `Msg_${_textType}` ] || item[ `Msg_${_defType}` ];
            item[ 'textColor' ] = new cc.Color( _r, _g, _b );
        })

        return _propCfgList;
    }

    /**
     * 获取粮票收集数据列表
     * @param type 收集类型
     */
    onPaperDataList_blxf ( type: number ) {
        let _paperDataList: any[] = [];

        let { CSV_PAPER } = EnumManager_blxf.instance.getGameCsvType();
        let _paperCfgList: any[] = CsvManager_blxf.instance.getCsvDataByName_blxf( CSV_PAPER );
        _paperDataList = _paperCfgList.filter( item =>{
            let { RewardType, RewardNum } = item;
            item[ `rewardType` ] = Number( RewardType );
            item[ `rewardNum`  ] = Number( RewardNum );
            return item[ `Type` ] == type;
        })

        return _paperDataList;
    }

    /**
     * 获取粮票收集数据
     * @param type 收集类型 1: 菜谱、2: 进货单、3: 货源
     * @param condition 收集条件
     * @returns 返回收集数据
     */
    onPaperData_blxf ( type: number, condition: any ) {
        let _paperData: any = {};

        let _paperDataList: any[] = this.onPaperDataList_blxf( type );
        _paperData = _paperDataList.find( item =>{
            return item[ `Condition` ] == condition;
        })

        return _paperData;
    }

    getNowPetData_blxf ( a: any, b: any ) {

    }
    

    getDecorationDataList_blxf ( type: number = 1 ) {
        let _renovationList: any[] = [], _stateList: any[] = [];

        let _dataList: any[] = this.getDecorationData_blxf( type );
        _dataList.forEach( cfgItem =>{
            let { Type, isUnlock } = cfgItem;
            let _index: number = _renovationList.findIndex( item => item['typeName'] == Type );
            if ( _index == -1 ) {
                _renovationList.push( { typeName: Type, dataList: [ cfgItem ] } );
                if ( !isUnlock ) {
                    _stateList[ 0 ] = 1;
                    cfgItem.isShowUnlock = true;
                }
            } else {
                let _isFirstUnlock: boolean = _renovationList[ _index ].dataList[0].isUnlock;
                cfgItem._isFirstUnlock = _isFirstUnlock;

                _renovationList[ _index ].dataList.push( cfgItem );

                if ( _isFirstUnlock && !isUnlock && !_stateList[ _index ] ) {
                    _stateList[ _index ] = 1;

                    cfgItem.isShowUnlock = true;
                }
            }

            if ( !cfgItem.isShowUnlock ) return;

            let { consumeType, consumeNum } = cfgItem;
            cfgItem['isConsume'] = NumModule_blxf.instance.onCheckNum_blxf( consumeType, consumeNum );
        })

        return _renovationList;
    }


    /**
     * 获取自定义事件数据
     * @param eventId 事件id
     * @returns 返回事件数据
     */
    getReportEventData_blxf ( eventId: string ) {
        let _reportEventData: any;

        if ( eventId == '1' ) {
            _reportEventData = { 
                ID  : '1', SceneName: '1-新用户启动游戏' ,
                BranchId : 'BCBgAAoXHx5d1FEO89hZEg', EventType: '1', EventId: 'new_step_1'
            }
            return _reportEventData;
        }

        let { CSV_REPORT_EVENT } = EnumManager_blxf.instance.getGameCsvType();
        let _cfgReportEventData: any[] = this.getCsvDataByName_blxf( CSV_REPORT_EVENT );
        if ( !_cfgReportEventData ) return _reportEventData;

        _reportEventData = _cfgReportEventData.find( eventItem =>{
            return eventItem.ID == eventId;
        })

        !_reportEventData && UtilsModule_blxf.instance.Log_blxf(`查找自定义事件失败: eventId =>> ${eventId}`);

        return _reportEventData;
    }

    m_header = [];
    m_content = [];
    Fields = null;
    strField = '';

    mStateType = STATETYPE.NewFieldStart;

    /**
     * 
     * @param filePath 文件路径
     * @param callBack 回调函数
     */
    loadCsv_blxf ( filePath: string, callBack: any ) {
        this.m_content.length = 0;
        this.m_header.length = 0;
        this.Fields = new Row();
        this.strField = "";
        this.mStateType = STATETYPE.NewFieldStart;

        let _CsvBundle = BundleManager_blxf.instance.Bundle_Csv;
        _CsvBundle.load( filePath, (err, data) => {
            let _asset = data;

            if (err) {
                cc.log(` ----------------- 加载csv文件${filePath}失败，请检查路径是否正确!`);
                // cc.error(err.message, err);
                return;
            }
            try {
                let _dataStr: string = data.toString();
                // cc.log('filePath =', filePath, _dataStr);

                // todo 兼容
                if ( !_dataStr.includes('\r') ) {
                    // cc.log(data.length, data, '<== log');
                    _dataStr = _dataStr.replace(/\n/g, '\r\n');
                }

                for (var i = 0, size = _dataStr.length; i < size; ++i) {
                    var ch = _dataStr[i];
                    switch (this.mStateType) {
                        case STATETYPE.NewFieldStart: { // 新字段开始
                            if (ch == '"') {
                                this.mStateType = STATETYPE.QuotesField;
                            }
                            else if (ch == ',') {
                                this.Fields.push_back("");
                                this.mStateType = STATETYPE.FieldSeparator;
                            }
                            else if (ch == '\r' || ch == '\n') {
                                cc.log("语法错误：有空行");
                                this.mStateType = STATETYPE.Error;
                            }
                            else {
                                this.strField += ch;
                                this.mStateType = STATETYPE.NonQuotesField;
                            }
                        }
                            break;

                        case STATETYPE.NonQuotesField: { // 非引号字段
                            if (ch == ',') {
                                this.Fields.push_back(this.strField);
                                this.strField = "";
                                this.mStateType = STATETYPE.FieldSeparator;
                            }
                            else if (ch == '\r') {
                                this.Fields.push_back(this.strField);
                                this.mStateType = STATETYPE.RowSeparator;
                            }
                            else {
                                this.strField += ch;
                            }
                        }
                            break;

                        case STATETYPE.QuotesField: { // 引号字段
                            if (ch == '"') {
                                this.mStateType = STATETYPE.QuoteInQuotesField;
                            }
                            else {
                                this.strField += ch;
                            }
                        }
                            break;

                        case STATETYPE.FieldSeparator: { // 字段分隔
                            if (ch == ',') {
                                this.Fields.push_back("");
                            }
                            else if (ch == '"') {
                                this.strField = "";
                                this.mStateType = STATETYPE.QuotesField;
                            }
                            else if (ch == '\r') {
                                this.Fields.push_back("");
                                this.mStateType = STATETYPE.RowSeparator;
                            }
                            else {
                                this.strField += ch;
                                this.mStateType = STATETYPE.NonQuotesField;
                            }
                        }
                            break;

                        case STATETYPE.QuoteInQuotesField: { // 引号字段中的引号
                            if (ch == ',') {
                                // 引号字段闭合
                                this.Fields.push_back(this.strField);
                                this.strField = "";
                                this.mStateType = STATETYPE.FieldSeparator;
                            }
                            else if (ch == '\r') {
                                // 引号字段闭合
                                this.Fields.push_back(this.strField);
                                this.mStateType = STATETYPE.RowSeparator;
                            }
                            else if (ch == '"') {
                                // 转义
                                this.strField += ch;
                                this.mStateType = STATETYPE.QuotesField;
                            }
                            else {
                                cc.log("语法错误： 转义字符 \" 不能完成转义 或 引号字段结尾引号没有紧贴字段分隔符");
                                this.mStateType = STATETYPE.Error;
                            }
                        }
                            break;

                        case STATETYPE.RowSeparator: { // 行分隔符字符1，回车
                            if (ch == '\n') {
                                this.m_content.push(this.Fields);
                                this.Fields = new Row(); // self.Fields.clear();
                                this.strField = "";
                                this.mStateType = STATETYPE.NewFieldStart;
                            }
                            else {
                                cc.log("语法错误： 行分隔用了回车 \\r。但未使用回车换行 \\r\\n ", ch);
                                this.mStateType = STATETYPE.Error;
                            }
                        }
                            break;

                        case STATETYPE.Error: {
                            // 语法错误 modify by self
                            //                return;
                        }
                            break;

                        default:
                            break;
                    }
                }
                
                switch (this.mStateType) {
                    case STATETYPE.NewFieldStart: {
                        // Excel导出的CSV每行都以/r/n结尾。包括最后一行
                    }
                        break;

                    case STATETYPE.NonQuotesField: {
                        this.Fields.push_back(this.strField);
                        this.m_content.push(this.Fields);

                        
                    }
                        break;

                    case STATETYPE.QuotesField: {
                        cc.log("语法错误： 引号字段未闭合");
                    }
                        break;

                    case STATETYPE.FieldSeparator: {
                        this.Fields.push_back("");
                        this.m_content.push(this.Fields);
                    }
                        break;

                    case STATETYPE.QuoteInQuotesField: {
                        this.Fields.push_back(this.strField);
                        this.m_content.push(this.Fields);
                    }
                        break;

                    case STATETYPE.RowSeparator: {

                    }
                        break;

                    case STATETYPE.Error: {

                    }
                        break;

                    default: break;
                }

                this.setHeader();
            
                // cc.log('Result should be a data :' + _dataStr);
                this.m_content = this.contentToJson(this.m_content, filePath);

                // if (filePath.includes('Merchant')) cc.log('self.m_content', self.m_content)
                callBack(this.m_content);

                // // 用完释放资源
                // Loader.onReleaseAssets([ _asset ]);
            } catch (e) {
                console.warn('loadCsv error: ', filePath, e);

                // GameData.errorCsvStr = GameData.errorCsvStr || [];
                // let pathArr = filePath.split('/');
                // GameData.errorCsvStr.push(pathArr[pathArr.length-1]);

                callBack && callBack([]);
            }
        });
    };

    contentToJson (content, filePath) {
        var jsonArray = [];
        for (var i = 2; i < content.length; ++i) {
            var jsonObj = {};
            var headerObj = content[i].m_header;
            var valueObj = content[i].m_values;
            for (var j = 0; j < headerObj.length; ++j) {
                var value = valueObj[j];
                value = value.replace('\\n', '\n');
                jsonObj[headerObj[j]] = value;
            }
            jsonArray.push(jsonObj);
        }
        // if (filePath.includes('InteractiveConfig')) cc.log(typeof(jsonArray), jsonArray)
        return jsonArray;
    };

    setHeader () {
        this.m_header.length = 0;
        for (var i = 0; i < this.m_content[1].m_values.length; i++) {
            // console.log('i ==', i, this.m_content[1], this.m_content[1].m_values[i])
            this.m_header.push(this.m_content[1].m_values[i]);
        }
        for (var i = 0; i < this.m_content.length; i++) {
            if ( !this.m_content[i] ) continue;
            this.m_content[i].setHeader(this.m_header);
        }
    };

    // 获取列头字段
    getHeader () { return this.m_header; };
    // 获取总行数
    getRowCount () { return this.m_content.length; };
    // 获取总列数
    getColumnCount () { return this.m_header.length; };

    tisExistForKey ( key ) {
        for (var i = 0; i < this.m_header.length; ++i) {
            var strKey = this.m_header[i];
            if (strKey === key) {
                return true;
            }
        }

        return false;
    }

}
